package br.edu.ufcg.splab.techniques.reduction.requirement;

import java.util.HashSet;
import java.util.Set;

import br.edu.ufcg.splab.core.InterfaceEdge;
import br.edu.ufcg.splab.generator.TestCase;
import br.edu.ufcg.splab.generator.TestSuite;

public class TransitionPairsTracerGenerator implements InterfaceRequirementTracerGenerator {
	
	/**
	 * This method have the role of extract the transition pairs (requirements) from the test suite passed as 
	 * parameter.  
	 * @param root The root of the model that the suite was extracted.
	 * @param suite The suite to be related with the requirements.
	 * @return The tracer of the requirements to the test cases that satisfy them.
	 */	
	public RequirementTracer getTracer(TestSuite suite) {
		RequirementTracer tracer = new RequirementTracer();		
		for(String pair: getEdgePairs(suite)) {
			InterfaceRequirement req = new Requirement();
			req.setLabel(pair);
			for (TestCase test : suite.getTestSuite()) {
				if(containsEdgePairs(test, pair)){
					tracer.addTestCaseAndReq(test, req);
				}
			}
			tracer.addRequirement(req);
		}
		tracer.setTypeRequirement(this.getTypeRequirementTracer());
		return tracer;
	}
	
	public String getTypeRequirementTracer(){
		return "all-transition-pairs";
	}
			
	/**
	 * Provide the transition pairs of the graph.
	 * 
	 * @param testSuite The test suite
	 * @param root The root of the graph measured.
	 * @return Returns all transition pairs of the graph.
	 */
	private Set<String> getEdgePairs(TestSuite testSuite){
		Set<String> str = new HashSet<String>();
		for(TestCase tc : testSuite.getTestSuite()){
			str.addAll(this.getEdgePairs(tc));
		}
		return str;
	}
	
	/**
	 * Returns <tt>true</tt> if the test case contains the specified transition pair. 
	 * 
	 * @param testCase The test case for evaluation.
	 * @param transitionPair The transition pair whose presence in this test case is to be tested
	 * @return <tt>true</tt> if this list contains the specified transition pair. 
	 */
	private boolean containsEdgePairs(TestCase testCase, String transitionPair) {	
		for(String str: getEdgePairs(testCase)){
			if(str.equals(transitionPair)){
				return true;
			}
		}
		return false;
	}
	
	/**
	 * Returns the list of the transition pairs of the test case.
     *
	 * @param testCase The test case for evaluation.
	 * @return The set of the transition pairs.
	 */
	private Set<String> getEdgePairs(TestCase testCase){
		Set<String> pairs = new HashSet<String>();		
		String s1 = "";
		String s2 = "";
		for(InterfaceEdge edge: testCase.getTestCase()){
			if(s1.equals("")){
				s1 = edge.getLabel();
			}else if(s2.equals("")){
				s2 = edge.getLabel();
			}else{
				s1 = s2;
				s2 = edge.getLabel();
			}
			if(!s2.equals("")){
				pairs.add("(\"" + s1 + "\",\"" + s2 + "\")");
			}
		}
		if(s2.equals("")){
			pairs.add("(\"" + s1 + "\")");
		}
		return pairs;
	}
}